/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import liquibase.pro.packaged.B;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.plan.score.ByProblemSearchDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.ByScoreQuestionAppealEnum;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.StatusEnum;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.MaintainByScoreQuestionVO;
import org.springblade.modules.admin.mapper.MaintainByScoreQuestionMapper;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.admin.vo.MaintainPlanContentUserVO;
import org.springblade.modules.admin.vo.check.ProblemResultVo;
import org.springblade.modules.admin.vo.check.ProblemStatusVo;
import org.springblade.modules.admin.vo.plan.PlanMaintainUserVO;
import org.springblade.modules.admin.vo.plan.store.ByProblemResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 保养评分工作项评分问题 服务实现类
 *
 * @author ysq
 * @since 2024-05-14
 */
@Service
public class MaintainByScoreQuestionServiceImpl extends BaseServiceImpl<MaintainByScoreQuestionMapper, MaintainByScoreQuestion> implements IMaintainByScoreQuestionService {

	@Autowired
	private IMaintainCheckHistoryService maintainCheckHistoryService;

	@Autowired
	private ElevatorService elevatorService;

	@Autowired
	private MaintainMalfunctionLogService malfunctionLogService;

	@Autowired
	private IMaintainPlanContentService maintainPlanContentService;
	@Autowired
	private IMaintainPlanContentUserService planContentUserService;
	@Autowired
	private ByScoreQuestionAppealService byScoreQuestionAppealService;

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean addAndUpdate(MaintainByScoreQuestion maintainByScoreQuestion) {
		if (maintainByScoreQuestion.getCheckHistoryId() == null) {
			throw new ServiceException("工作项id不能为空");
		}
		MaintainByScoreQuestion scoreQuestion = this.getOne(Wrappers.<MaintainByScoreQuestion>lambdaQuery().eq(MaintainByScoreQuestion::getCheckHistoryId, maintainByScoreQuestion.getCheckHistoryId()));
		if (scoreQuestion != null) {
			if (scoreQuestion.getChildPlanId() != null) {
				throw new ServiceException("该工作项问题点已关联任务不能修改");
			}
			maintainByScoreQuestion.setId(scoreQuestion.getId());
			maintainByScoreQuestion.setPlanId(scoreQuestion.getPlanId());
			maintainByScoreQuestion.setElevatorId(scoreQuestion.getElevatorId());
			maintainByScoreQuestion.setBuildingId(scoreQuestion.getBuildingId());
			maintainByScoreQuestion.setStatus(scoreQuestion.getStatus());
		} else {
			if (Convert.toInt(maintainByScoreQuestion.getIsSign(), 0) == 0) {
				MaintainCheckHistory maintainCheckHistory = maintainCheckHistoryService.getById(maintainByScoreQuestion.getCheckHistoryId());
				if (maintainCheckHistory == null) {
					throw new ServiceException("工作项id有误");
				}

				BeanUtil.copyProperties(maintainCheckHistory, maintainByScoreQuestion);
				maintainByScoreQuestion.setId(null);
				maintainByScoreQuestion.setBuildingId(elevatorService.getById(maintainCheckHistory.getElevatorId()).getBuildingId());
			} else {
				MaintainMalfunctionLog malfunctionLog = malfunctionLogService.getById(maintainByScoreQuestion.getCheckHistoryId());
				MaintainPlanContent planContent = maintainPlanContentService.getById(malfunctionLog.getPlanId());
				maintainByScoreQuestion.setPlanId(malfunctionLog.getPlanId());
				maintainByScoreQuestion.setElevatorId(planContent.getElevatorId());
				maintainByScoreQuestion.setLocationTypeName("任务追踪");
				maintainByScoreQuestion.setTltNames("任务追踪");
				maintainByScoreQuestion.setName("打卡签字");
				maintainByScoreQuestion.setBuildingId(elevatorService.getById(planContent.getElevatorId()).getBuildingId());
			}
			maintainByScoreQuestion.setStatus(StatusEnum.DISABLE.getId());
		}
		Boolean result = this.saveOrUpdate(maintainByScoreQuestion);
		this.updateByScoreQuestionAppealData(maintainByScoreQuestion);
		return result;
	}

	private void updateByScoreQuestionAppealData(MaintainByScoreQuestion entity) {

		List<MaintainByScoreQuestion> list = super.list(Wrappers.<MaintainByScoreQuestion>lambdaQuery().eq(MaintainByScoreQuestion::getPlanId,entity.getPlanId()));
		MaintainByScoreQuestionAppeal appeal = byScoreQuestionAppealService.getOne(Wrappers.<MaintainByScoreQuestionAppeal>lambdaQuery().eq(MaintainByScoreQuestionAppeal::getPlanId,entity.getPlanId()), Boolean.FALSE);
		if(Func.isEmpty(appeal)){
			appeal = new MaintainByScoreQuestionAppeal();
			appeal.setPlanId(entity.getPlanId());
			appeal.setBuildingId(entity.getBuildingId());
			appeal.setElevatorId(entity.getElevatorId());
			appeal.setQuestionCount(list.size());
			long appealCount = list.stream().filter(e -> e.getScoreIssueStatus().equals(1)).count();
			if(appealCount > 0){
				appeal.setAppealType(ByScoreQuestionAppealEnum.APPEAL_TYPE_2.getId());
			}else {
				appeal.setAppealType(ByScoreQuestionAppealEnum.APPEAL_TYPE_1.getId());
				appeal.setAppealStatus(ByScoreQuestionAppealEnum.APPEAL_STATUS_1.getId());
			}
			List<PlanMaintainUserVO> userVOS = planContentUserService.selectWorkUsers(entity.getPlanId());
			appeal.setPlanUserIds(userVOS.stream().map(e -> String.valueOf(e.getMaintainUserId())).collect(Collectors.joining(",")));
			appeal.setPlanUserNames(userVOS.stream().map(e -> String.valueOf(e.getMaintainName())).collect(Collectors.joining(",")));
		}else {
			if(ByScoreQuestionAppealEnum.APPEAL_TYPE_2.getId() == appeal.getAppealType() || ByScoreQuestionAppealEnum.APPEAL_STATUS_1.getId() == appeal.getAppealStatus()){
				appeal.setQuestionCount(list.size());
				long appealCount = list.stream().filter(e -> e.getScoreIssueStatus().equals(1)).count();
				if(appealCount > 0){
					appeal.setAppealType(ByScoreQuestionAppealEnum.APPEAL_TYPE_2.getId());
					appeal.setAppealStatus(null);
				}else {
					appeal.setAppealType(ByScoreQuestionAppealEnum.APPEAL_TYPE_1.getId());
					appeal.setAppealStatus(ByScoreQuestionAppealEnum.APPEAL_STATUS_1.getId());
				}
			}
		}
		byScoreQuestionAppealService.saveOrUpdate(appeal);
	}


	@Override
	public ProblemStatusVo getProblemStatus() {
		return baseMapper.getProblemStatus();
	}

	@Override
	public IPage<ByProblemResultVo> getProblemResultList(ByProblemSearchDTO byProblemSearchDTO) {
		Query query = new Query();
		query.setSize(byProblemSearchDTO.getSize());
		query.setCurrent(byProblemSearchDTO.getCurrent());
		IPage<ByProblemResultVo> page = Condition.getPage(query);
		List<ByProblemResultVo> list = baseMapper.getProblemResultList(page, byProblemSearchDTO);
		List<Long> planIds = list.stream().map(ByProblemResultVo::getPlanId).collect(Collectors.toList());
		if (planIds.size() > 0) {
			List<MaintainByScoreQuestion> planQuList = this.list(Wrappers.<MaintainByScoreQuestion>lambdaQuery().in(MaintainByScoreQuestion::getPlanId, planIds));
			Map<Long, List<MaintainByScoreQuestion>> listMap = planQuList.stream().collect(Collectors.groupingBy(MaintainByScoreQuestion::getPlanId));
			for (ByProblemResultVo byProblemResultVo : list) {
				List<MaintainByScoreQuestion> scoreQuestions = listMap.get(byProblemResultVo.getPlanId());
				byProblemResultVo.setProblemCounts(scoreQuestions.size());
				byProblemResultVo.setEnProblemCounts(scoreQuestions.stream().filter(o -> o.getChildPlanId() != null).collect(Collectors.toList()).size());
				byProblemResultVo.setDisProblemCounts(scoreQuestions.stream().filter(o -> o.getChildPlanId() == null).collect(Collectors.toList()).size());
				List<MaintainByScoreQuestion> childList = baseMapper.getQuestionList(byProblemResultVo.getQueIds());
				List<MaintainByScoreQuestion> questions = childList.stream().filter(o -> o.getIssueType() != null && o.getIssueType() == 1).collect(Collectors.toList());
				if(questions.size()>0){
					byProblemResultVo.setIsPass(0);
				}
				byProblemResultVo.setList(childList);
			}
		}
		page.setRecords(list);
		return page;
	}

	@Override
	public List<ByProblemResultVo> downExcel(ByProblemSearchDTO byProblemSearchDTO) {
		return baseMapper.downExcel(byProblemSearchDTO);
	}
}
